// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.UI;
using CommunityServer.Components;
using CommunityServer.Controls;
using System.Text;
using System.IO;
using System.Collections.Specialized;
using System.ComponentModel;
using TW = Telligent.Glow;

[assembly: WebResource("CommunityServerStuff.Controls.CallbackPager.js", "text/javascript")]
namespace CommunityServerStuff.Controls
{
    /// <summary>
    /// Pager control that pages using AJAX callbacks.
    /// </summary>
    public class CallbackPager : PreTemplatedPagerBase, TW.ICallbackEventHandler, IPostBackDataHandler
    {
        private int _pageIndex = -1;
        private Control _pagedContentControl = null;
        TW.CallbackManager _callbackManager = null;
        bool _creatingChildControls = false;
        bool _raiseDelayedCallbackEvent = false;

        /// <summary>
        /// Template to be rendered as the paged content of the control.
        /// </summary>
        [
        Browsable(false),
        DefaultValue(null),
        Description("Defines the ITemplate to be rendered as the paged content of the control."),
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        public virtual ITemplate PagedContent
        {
            get { return _pagedContent; }
            set { _pagedContent = value; }
        }
        private ITemplate _pagedContent;

        public override void DataBind()
        {
            if (!this.Controls.IsReadOnly && _pageIndex != this.PageIndex)
            {
                _pageIndex = this.PageIndex;
                base.DataBind();
            }
        }

        protected override void BindDefaultContent(Control control, IDataItemContainer dataItemContainer)
        {
            if (ShowPagerItems && TotalPages > 1)
            {
                if (ShowFirst)
                    BindFirst(control);

                if (ShowPrevious)
                    BindPrevious(control);

                if (ShowIndividualPages)
                    BindPages(control);

                if (ShowNext)
                    //BindNext(control);

                if (ShowLast)
                    BindLast(control);
            }
        }

        protected override void EnsureChildControls()
        {
            base.EnsureChildControls();

            if (_raiseDelayedCallbackEvent)
            {
                _raiseDelayedCallbackEvent = false;
                DataBind();
                PageIndexChanged(this, new PagerEventArgs(this.PageSize, this.PageIndex, this.TotalRecords));
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            base.RecreateChildControlsOnDataBind = true;
        }

        protected override void CreateChildControls()
        {
            _creatingChildControls = true;
            base.CreateChildControls();
            _creatingChildControls = false;
        }

        protected override void  CreateControlHierarchy()
        {
            if (_callbackManager == null)
                _callbackManager = new TW.CallbackManager(this);

            this.Controls.Add(_callbackManager);

            this.Controls.Add(new LiteralControl(string.Format("<input type=\"hidden\" name=\"{0}\" value=\"{1}\" />", this.UniqueID, this.PageIndex)));

            base.CreateControlHierarchy();

            if (PagedContent != null && _pagedContentControl != null)
                this.PagedContent.InstantiateIn(_pagedContentControl);
        }

        protected override void AddContentControls()
        {
            if (PagedContent != null)
            {
                _pagedContentControl = new WrappedControlItem(this, 0, 0);
                this.Controls.Add(_pagedContentControl);
            }

            base.AddContentControls();
        }

        #region Callback Handler

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            TW.ClientScripts.RegisterScriptsForCommon(this);
            CSControlUtility.Instance().RegisterClientScriptResource(this, typeof(CallbackPager), "CommunityServer.Controls.Pagers.CallbackPager.js");

            CSControlUtility.Instance().RegisterStartupScript(this, typeof(CallbackPager), this.ClientID, string.Format(
                "<script type=\"text/javascript\">\n// <![CDATA[\nwindow.{0} = new CallbackPager('{0}','{1}','{2}');\n// ]]>\n</script>",
                this.ClientID,
                this.ClientID + "_Container",
                _callbackManager.GetCallbackEventReference(this, "page", "callback", "", "errorCallback", false)
                ), false);
        }

        protected override string GetPageNavigateUrl(int pageIndex)
        {
            return string.Format("javascript:{0}.GoToPage({1})", this.ClientID, pageIndex.ToString());
        }

        protected string _callbackArgument = null;

        string TW.ICallbackEventHandler.GetCallbackResult()
        {
            using (StringWriter stringWriter = new StringWriter())
            {
                using (HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter))
                {
                    Render(htmlWriter, false);
                    return stringWriter.ToString();
                }
            }
        }

        void TW.ICallbackEventHandler.RaiseCallbackEvent(string argument)
        {
            int pageIndex = int.Parse(argument) - 1;
            PageIndex = pageIndex;

            if (_creatingChildControls)
                _raiseDelayedCallbackEvent = true;
            else
            {
                DataBind();
                PageIndexChanged(this, new PagerEventArgs(this.PageSize, this.PageIndex, this.TotalRecords));
            }
        }

        #endregion

        #region Render functions

        protected override void Render(HtmlTextWriter writer)
        {
            Render(writer, true);
        }

        protected virtual void Render(HtmlTextWriter writer, bool renderContainer)
        {
            if (renderContainer)
                writer.Write("<div id=\"" + this.ClientID + "_Container\">");

            base.Render(writer);

            if (renderContainer)
                writer.Write("</div>");
        }

        #endregion

        protected override int GetInitialPageIndex()
        {
            return -1;
        }

        #region IPostBackDataHandler Members

        bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
        {
            if (_callbackManager == null || !_callbackManager.IsCallback)
            {
                int pageIndex = int.Parse(postCollection[postDataKey]);
                if (pageIndex != this.PageIndex)
                {
                    this.PageIndex = pageIndex;
                    return true;
                }
            }

            return false;
        }

        void IPostBackDataHandler.RaisePostDataChangedEvent()
        {
            // nothing to do
        }

        #endregion
    }
}
